use std::fmt::{Display, Formatter};
use std::ops::Add;
use std::path::Component::Prefix;
use std::str::FromStr;
use num::pow;

#[derive(Debug,Default)]
struct Point {
    x: f32,
    y: f32,
}


// impl Default for Point {
//     fn default() -> Point {
//         return Point {x:0.0,y:0.0}
//     }
// }

impl Display for Point {
    fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
        write!(f, "({}, {})", self.x, self.y)
    }
}

impl Add for Point {
    type Output = Point;
    fn add(self, other: Point) -> Point {
        Point {
            x: self.x + other.x,
            y: self.y + other.y,
        }
    }
}


impl From<(f32, f32)> for Point {
    fn from(p: (f32, f32)) -> Point {
        Point {
            x: p.0,
            y: p.1,
        }
    }
}

impl FromStr for Point {
    type Err = ();
    fn from_str(s: &str) -> Result<Point, ()> {
        let mut parts = s.split(',');
        let x_str = parts.next().ok_or(())?;
        let y_str = parts.next().ok_or(())?;
        // 不允许有更多部分
        if parts.next().is_some() {
            return Err(());
        }
        // 解析为f32，任意一个失败就返回Err(())
        let x: f32 = x_str.trim().parse().map_err(|_| ())?;
        let y: f32 = y_str.trim().parse().map_err(|_| ())?;
        Ok(Point { x, y })
    }
}

fn main() {

    let p1 = Point::default();

    let p2 = Point {x: 1.0, y: 2.0};
    // print!("{:?}", p);

    let p = p1 + p2;
    // because impl Display
    println!("{}", p);


    let p3 = Point::from((1.0, 2.0));

    let p4 = Point::from_str("1.1,1.2").unwrap();
    println!("{}", p4);


}